package com.seari.main.line17;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.seari.bean.iec104.DataTransferBean;
import com.seari.bean.iec104.SimpleMetric;
import com.seari.utils.JedisPoolUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.springframework.util.StringUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Pipeline;

public class Line17SlaveWorker implements Runnable
{
	public static String MQ_HOST;
	public static int MQ_PORT;
	public static String MQ_VIRTUALHOST;
	public static String MQ_USER;
	public static String MQ_PASS;
	public static String MQ_EXCHANGE;
	public static String MQ_ROUTINGKEY;
	private static ObjectMapper mapper = new ObjectMapper();
    private String group;
    private int gap;
    private List<DataTransferBean> jobList;
    private List<SimpleMetric> sendList = new ArrayList<>();
    private boolean terminate = false;
    private final static int LINE_17 = 17;
    private Channel channel;
    final static Logger logger = LoggerFactory.getLogger(Line17SlaveWorker.class);

	@Override
	public void run()
	{
		// TODO Auto-generated method stub
		Jedis jedis = null;
		ConnectionFactory factory = new ConnectionFactory();
        factory.setHost(MQ_HOST);
        factory.setPort(MQ_PORT);
        factory.setVirtualHost(MQ_VIRTUALHOST);
        factory.setUsername(MQ_USER);
        factory.setPassword(MQ_PASS);
        Connection connection = null;
		try
		{
			jedis = JedisPoolUtils.getJedis();
			Pipeline pipeline = jedis.pipelined();
			connection = factory.newConnection();
        	channel = connection.createChannel();
			while(!terminate)
			{
				sendList.clear(); //清空上次发送数据
				for (DataTransferBean dataTransferBean : jobList)
				{
					pipeline.hget(dataTransferBean.getTableName(), dataTransferBean.getActualAddress() + "");
				}
				List<Object> results = pipeline.syncAndReturnAll();
				for(int i = 0; i < jobList.size();i++)
				{
					DataTransferBean dataTtransferBean = jobList.get(i);
					String result = (String) results.get(i);
					if(StringUtils.isEmpty(result))
					{
						result = "0";
					}
					SimpleMetric simpleMetric = new SimpleMetric();
					if(dataTtransferBean.getType().equals("bool"))
					{
						simpleMetric.setType("YX");
						simpleMetric.setCompany("seisys");
						simpleMetric.setDevice(dataTtransferBean.getComment());
						simpleMetric.setIoa(Integer.parseInt(dataTtransferBean.getAddress()));
						simpleMetric.setLine(LINE_17);
						simpleMetric.setSystem(dataTtransferBean.getSystemType());
						simpleMetric.setStation(dataTtransferBean.getStationEn());
						simpleMetric.setTimestampNs(System.currentTimeMillis() * 1000);
						int value = Integer.parseInt(result);
						if(dataTtransferBean.getReverse())
						{
							if(value == 0)
							{
								simpleMetric.setValue(1f);
							}else {
								simpleMetric.setValue(0f);
							}
						}else {
							if(value == 0)
							{
								simpleMetric.setValue(0f);
							}else {
								simpleMetric.setValue(1f);
							}
						}
					}else if (dataTtransferBean.getType().equals("int16")) {
						simpleMetric.setType("YC");
						simpleMetric.setCompany("seisys");
						simpleMetric.setDevice(dataTtransferBean.getComment());
						simpleMetric.setIoa(Integer.parseInt(dataTtransferBean.getAddress()));
						simpleMetric.setLine(LINE_17);
						simpleMetric.setSystem(dataTtransferBean.getSystemType());
						simpleMetric.setStation(dataTtransferBean.getStationEn());
						simpleMetric.setTimestampNs(System.currentTimeMillis() * 1000);
						int value = Integer.parseInt(result);
						simpleMetric.setValue((float)(Math.round(dataTtransferBean.getRatio() * value * 100))/100);
					}else if (dataTtransferBean.getType().equals("float"))
					{
						simpleMetric.setType("YC");
						simpleMetric.setCompany("seisys");
						simpleMetric.setDevice(dataTtransferBean.getComment());
						simpleMetric.setIoa(Integer.parseInt(dataTtransferBean.getAddress()));
						simpleMetric.setLine(LINE_17);
						simpleMetric.setSystem(dataTtransferBean.getSystemType());
						simpleMetric.setStation(dataTtransferBean.getStationEn());
						simpleMetric.setTimestampNs(System.currentTimeMillis() * 1000);
						float value = Float.parseFloat(result);
						simpleMetric.setValue(value * dataTtransferBean.getRatio());
					}
//					TransferDataDetail detail = new TransferDataDetail();
//					detail.setDevice_id(transferBean.getPointCode()); //device id暂时使用描述代替，待修改
//					detail.setDevice_name(transferBean.getDeviceId());
//					detail.setInfo(transferBean.getComment());
//					detail.setModbus_address(transferBean.getActualAddress() + "");
//					detail.setModbus_reference(transferBean.getBitAddress() + "");
//					if("float".equals(transferBean.getType()) && 1 == transferBean.getCombine()) //处理float转发
//					{
//						int lowVal = Integer.parseInt(result); //低位
//						String result2 =jedis.hget(transferBean.getTableName(), transferBean.getActualAddress() + 1 + "");
//						if(StringUtils.isEmpty(result2))
//						{
//							result2 = "0";
//						}
//						int highVal = Integer.parseInt(result2); //高位
//						float floatVal = DataUtils.getFloatValue(lowVal, highVal);
//						detail.setDevice_status(floatVal + "");
//					}else {
//						detail.setDevice_status(result);
//					}
//					sendList.add(detail);
					sendList.add(simpleMetric);
				}
				if(sendList.size() > 0)
				{
					String jsonStr = mapper.writeValueAsString(sendList);
					logger.info("slave worker send data ");
					channel.basicPublish(MQ_EXCHANGE, MQ_ROUTINGKEY, new AMQP.BasicProperties.Builder().contentType("application/json").contentEncoding("UTF-8").deliveryMode(1).build(), jsonStr.getBytes("UTF-8"));
				}
				TimeUnit.SECONDS.sleep(gap);
			}
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}finally
		{
			//关闭rabbitmq连接
			try
			{
				if(null != channel)
				{
					channel.close();
				}
				
				if(null != connection)
				{
					connection.close();
				}
			} catch (IOException e)
			{
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (TimeoutException e)
			{
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			//关闭JEDIS
			jedis.close();
			
			//终止标志不为真时，认为此线程非正常退出，进行线程重启
            if(!terminate)
            {
                try
                {
                    TimeUnit.SECONDS.sleep(2);
                    Thread.currentThread().interrupt();
                } catch (Exception e2)
                {
                    // TODO: handle exception
                }
                new Thread(this).start();
            }
		}
	}

    public String getGroup() {
        return group;
    }

    public void setGroup(String group) {
        this.group = group;
    }

    public int getGap() {
        return gap;
    }

    public void setGap(int gap) {
        this.gap = gap;
    }

    public List<DataTransferBean> getJobList() {
        return jobList;
    }

    public void setJobList(List<DataTransferBean> jobList) {
        this.jobList = jobList;
    }
        
}
